home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Graphics 2D / Super Snapshot / AEventStuff.c next >
Encoding:
C/C++ Source or Header  |  2000-10-06  |  12.7 KB  |  443 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        AEvents.c
  3.  
  4.     Contains:    This file contains an assortment of functions to deal with
  5.                 the Apple Events needed to set the OS 9 desktop.  The majority of
  6.                 the functionality below came from MoreAppleEvents, but it was not
  7.                 yet carbonized (to my knowledge) when I created this sample, so I could
  8.                 not directly link with the library that comes with that example.
  9.                 Special thanks to GeoWar for help in this area.                    
  10.  
  11.     Written by:     
  12.  
  13.     Copyright:    Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved.
  14.  
  15.                 You may incorporate this Apple sample source code into your program(s) without
  16.                 restriction. This Apple sample source code has been provided "AS IS" and the
  17.                 responsibility for its operation is yours. You are not permitted to redistribute
  18.                 this Apple sample source code as "Apple sample source code" after having made
  19.                 changes. If you're going to re-distribute the source, we require that you make
  20.                 it clear in the source that the code was descended from Apple sample source
  21.                 code, but that you've made changes.
  22.             
  23. */
  24.  
  25. #include "Snapshot.h"
  26.  
  27. static int gNumMonitors = 0;
  28.  
  29. OSErr SetDesktopPict(AEDesc* pAEDesc,SInt32 pIndex)
  30. {
  31.     OSErr anErr = noErr;
  32.     AppleEvent theEvent = {typeNull, nil};    //    always init AEDescs
  33.     ProcessSerialNumber tPSN;
  34.  
  35.     gNumMonitors = 0;    // zero monitor count
  36.     {
  37.         GDHandle tGDHandle = DMGetFirstScreenDevice(true);
  38.         while (tGDHandle)
  39.         {
  40.             gNumMonitors++;    // bump count
  41.             tGDHandle = DMGetNextScreenDevice(tGDHandle,true);
  42.         }
  43.     }
  44.     if (gNumMonitors == 0)
  45.         gNumMonitors = 1;
  46.  
  47.     // Launch reciever if it's not already running.
  48.     anErr = LaunchProcessBySignature('APPC', 'apcp',&tPSN);
  49.     if (anErr != noErr)
  50.         return anErr;
  51.  
  52.             //moreisbetter or AEHelpers
  53.     anErr = AEHMakeEventSignatureTarget('APPC', 'apcp', kAECoreSuite, kAESetData, &theEvent);
  54.     if (anErr == noErr)    // if it worked
  55.     {
  56.         AEDesc containerObj = {typeNull, nil};        // always init AEDescs
  57.         AEDesc propertyObject = {typeNull, nil};    // always init AEDescs
  58.  
  59.         anErr = MakePictureProperty(pIndex,&containerObj, &propertyObject);
  60.         if (anErr == noErr)    // if it worked
  61.         {
  62.             anErr = AEPutParamDesc(&theEvent, keyDirectObject, &propertyObject);
  63.             AEDisposeDesc(&propertyObject);        // Always dispose ASAP
  64.  
  65.             if (anErr == noErr)    // if it worked
  66.             {
  67.                 AEDesc tAEObject = {typeNull, nil};    // always init AEDescs
  68.  
  69.                 anErr = AECoerceDesc(pAEDesc,typeAlias,&tAEObject);    // coerce pAEDesc to type alias
  70.                 if (anErr == noErr)    // if it worked
  71.                 {
  72.                     anErr = AEPutParamDesc(&theEvent, keyAEData, &tAEObject);
  73.                     AEDisposeDesc(&tAEObject);    // Always dispose ASAP
  74.                     if (anErr == noErr)    // if it worked
  75.                     {
  76.                         anErr = AEHSendEventNoReturnValue(nil, &theEvent);
  77.                     }
  78.                 }
  79.             }
  80.         }
  81.         AEDisposeDesc(&theEvent);    // Always dispose ASAP
  82.     }
  83.     if (anErr != noErr)
  84.         DebugStr("\p|Set_DesktopPict-I-Error;error r30;");
  85.     return anErr;
  86. }
  87.  
  88. static OSErr MakePictureProperty(SInt32 pIndex,
  89.                               AEDesc* containerObjPtr,
  90.                               AEDesc* propertyObjPtr)
  91. {
  92.     AEDesc longAEDesc = {typeNull, nil};    // always init AEDescs
  93.     SInt32 index = ((pIndex - 1) % gNumMonitors) + 1;
  94.     OSErr anErr = AECreateDesc(typeSInt32, &index, sizeof(long), &longAEDesc);
  95.  
  96.     if (anErr == noErr)    // if it worked
  97.     {
  98.         AEDesc cmonAEDesc = {typeNull, nil};    // always init AEDescs
  99.  
  100.         // 'cmon' is nth (pIndex) color monitor object
  101.         anErr = CreateObjSpecifier('cmon',containerObjPtr,formAbsolutePosition,&longAEDesc,false,&cmonAEDesc);
  102.         AEDisposeDesc(&longAEDesc);    // Always dispose ASAP
  103.  
  104.         if (anErr == noErr)    // if it worked
  105.         {
  106.             AEDesc dpicDesc = {typeNull, nil};    // always init AEDescs
  107.             OSType dpicOSType = 'dpic';            // Desktop Picture
  108.  
  109.             anErr = AECreateDesc('type', &dpicOSType, sizeof(OSType), &dpicDesc);
  110.             if (anErr == noErr)    // if it worked
  111.             {
  112.                 anErr = CreateObjSpecifier(typeProperty,&cmonAEDesc,formPropertyID,&dpicDesc,false,propertyObjPtr);
  113.                 AEDisposeDesc(&cmonAEDesc);    // Always dispose ASAP
  114.             }
  115.         }
  116.     }
  117.     return anErr;
  118. }
  119.  
  120. pascal    OSErr    OHMakeAliasDescFromFSSpec( const FSSpecPtr fssPtr,
  121.                                                   AEDesc *aliasDescPtr )
  122. {
  123.     OSErr            anErr = noErr;
  124.     AliasHandle        aliasHandle;
  125.     
  126.     anErr = NewAlias( nil, fssPtr, &aliasHandle);
  127.     if ( anErr == noErr  &&  aliasHandle == nil )
  128.     {
  129.         anErr = paramErr;
  130.     }
  131.  
  132.     if ( anErr == noErr )
  133.     {
  134.         anErr = OHMakeAliasDesc( aliasHandle, aliasDescPtr );
  135.         DisposeHandle( (Handle)aliasHandle );
  136.     }
  137.         
  138.     return anErr;
  139. }//end MakeAliasObject
  140.  
  141. pascal    OSErr    OHMakeAliasDesc( const AliasHandle aliasHandle,
  142.                                         AEDesc *aliasDescPtr )
  143. {
  144.     OSErr    anErr = noErr;
  145.     
  146.     char    handleState = HGetState( (Handle)aliasHandle );
  147.     HLock( (Handle)aliasHandle );
  148.     
  149.     anErr = AECreateDesc( typeAlias, *aliasHandle, GetHandleSize( (Handle)aliasHandle ), aliasDescPtr );
  150.     
  151.     HSetState( (Handle)aliasHandle, handleState );
  152.     
  153.     return anErr;
  154. }//end MakeAliasObject
  155.  
  156. pascal    OSErr    AEHMakeEventSignatureTarget( const OSType targetType,
  157.                                                   const OSType targetCreator,
  158.                                                   const AEEventClass eventClass,
  159.                                                   const AEEventID eventID,
  160.                                                         AppleEvent *theEventPtr )
  161. {
  162.     OSErr    anErr = noErr;
  163.     
  164.     ProcessSerialNumber        psn = { kNoProcess, kNoProcess };
  165.     
  166.     anErr = FindProcessBySignature( targetType, targetCreator, &psn );
  167.     if ( anErr == noErr )
  168.     {
  169.         anErr = AEHMakeEventProcessTarget( &psn, eventClass, eventID, theEventPtr );
  170.     }
  171.     return anErr;
  172. }//end AEHMakeEventSignatureTarget
  173.  
  174. pascal    OSErr    AEHMakeEventProcessTarget( const ProcessSerialNumberPtr psnPtr,
  175.                                            const AEEventClass eventClass,
  176.                                            const AEEventID eventID,
  177.                                                  AppleEvent *theEventPtr )
  178. {
  179.     OSErr    anErr = noErr;
  180.     AEDesc    targetAppDesc = { typeNull, nil };
  181.     
  182.     anErr = AECreateDesc (typeProcessSerialNumber, psnPtr, sizeof( ProcessSerialNumber ), &targetAppDesc);
  183.  
  184.     if ( anErr == noErr )
  185.     {
  186.         anErr = AECreateAppleEvent( eventClass, eventID, &targetAppDesc,
  187.                                     kAutoGenerateReturnID, kAnyTransactionID, theEventPtr);
  188.     }
  189.     
  190.     AEDisposeDesc( &targetAppDesc );
  191.     
  192.     return anErr;
  193. }//end AEHMakeEventProcessTarget
  194.  
  195. pascal    OSErr    AEHSendEventNoReturnValue( const AEIdleUPP idleProcUPP,
  196.                                            const AppleEvent *theEvent )
  197. {
  198.     OSErr        anErr = noErr;
  199.     AppleEvent    theReply = { typeNull, nil };
  200.     AESendMode    sendMode;
  201.     
  202.     if ( idleProcUPP == nil )
  203.         sendMode = kAENoReply;
  204.     else
  205.         sendMode = kAEWaitReply;
  206.  
  207.     anErr = AESend( theEvent, &theReply, sendMode, kAENormalPriority, kNoTimeOut, idleProcUPP, nil );
  208.     if ( anErr == noErr  &&  sendMode == kAEWaitReply )
  209.     {
  210.         anErr =  AEHGetHandlerError( &theReply );
  211.     }
  212.     (void) AEDisposeDesc( &theReply );
  213.     
  214.     return anErr;
  215. }//end AEHSendEventNoReturnValue
  216.  
  217. pascal    OSErr    AEHGetHandlerError( const AppleEvent *reply )
  218. {
  219.     OSErr        anErr = noErr;
  220.     OSErr        handlerErr;
  221.     
  222.     DescType    actualType;
  223.     long        actualSize;
  224.     
  225.     if ( reply->descriptorType != typeNull )    // there's a reply, so there may be an error
  226.     {
  227.         OSErr    getErrErr = noErr;
  228.         
  229.         getErrErr = AEGetParamPtr( reply, keyErrorNumber, typeShortInteger, &actualType,
  230.                                     &handlerErr, sizeof( OSErr ), &actualSize );
  231.         
  232.         if ( getErrErr != errAEDescNotFound )    // found an errorNumber parameter
  233.         {
  234.             anErr = handlerErr;                    // so return it's value
  235.         }
  236.     }
  237.     return anErr;
  238. }//end AEHGetHandlerError
  239.  
  240. pascal    OSErr    FindProcessBySignature( const OSType targetType,
  241.                                         const OSType targetCreator,
  242.                                               ProcessSerialNumberPtr psnPtr )
  243. {
  244.     OSErr        anErr = noErr;
  245.     Boolean        lookingForProcess = true;
  246.     
  247.     ProcessInfoRec    infoRec;
  248.     
  249.     infoRec.processInfoLength = sizeof( ProcessInfoRec );
  250.     infoRec.processName = nil;
  251.     infoRec.processAppSpec = nil;
  252.     
  253.     psnPtr->lowLongOfPSN = kNoProcess;
  254.     psnPtr->highLongOfPSN = kNoProcess;
  255.  
  256.     while ( lookingForProcess )
  257.     {
  258.         anErr = GetNextProcess( psnPtr );
  259.         if ( anErr != noErr )
  260.         {
  261.             lookingForProcess = false;
  262.         }
  263.         else
  264.         {
  265.             anErr = GetProcessInformation( psnPtr, &infoRec );
  266.             if ( ( anErr == noErr )
  267.                  && ( infoRec.processType == targetType )
  268.                  && ( infoRec.processSignature == targetCreator ) )
  269.             {
  270.                 lookingForProcess = false;
  271.             }
  272.         }
  273.     }
  274.     
  275.     return anErr;
  276. }//end FindProcessBySignature
  277.  
  278. OSErr LaunchProcessBySignature(
  279.     const OSType pTargetType,const OSType pTargetCreator,ProcessSerialNumberPtr psnPtr)
  280. {
  281.     FSSpec appFSSpec;
  282.     OSErr anErr = FindProcessBySignature(pTargetType, pTargetCreator, psnPtr);
  283.  
  284.     if (anErr == noErr)    // already running
  285.         return anErr;
  286.  
  287.     // It's not already running, so look for it (as an APPL) in the desktop database
  288.     if (pTargetType == 'APPL')
  289.         anErr = Find_DTDB_APPL(pTargetCreator,&appFSSpec);
  290.  
  291.     // If we haven't found it yet, search all the volumes
  292.     if (anErr != noErr)
  293.         anErr = Search_Volumes(pTargetType,pTargetCreator,&appFSSpec);
  294.  
  295.     // we found it, so try to launch it
  296.     if (anErr == noErr)
  297.     {
  298.         LaunchParamBlockRec tLaunchPB;
  299.  
  300.         tLaunchPB.launchBlockID = extendedBlock;
  301.         tLaunchPB.launchEPBLength = extendedBlockLen;
  302.         tLaunchPB.launchFileFlags = nil;
  303.         tLaunchPB.launchControlFlags = launchContinue + launchNoFileFlags + launchDontSwitch;
  304.         tLaunchPB.launchAppSpec = &appFSSpec;
  305.  
  306.         anErr = LaunchApplication(&tLaunchPB);
  307.         if (anErr == noErr)
  308.             *psnPtr = tLaunchPB.launchProcessSN;
  309.     }
  310.     return anErr;
  311. }
  312.  
  313. static OSErr Search_Volumes(const OSType pTargetType,const OSType pTargetCreator,FSSpec* pFSSpecPtr)
  314. {
  315.     SInt16    index;
  316.     OSErr    anErr = noErr;
  317.  
  318.     for (index = 1;;index++)    // for each volume...
  319.     {
  320.         XVolumeParam    tXVPV;
  321.  
  322.         tXVPV.ioCompletion = nil;
  323.         tXVPV.ioNamePtr = nil;
  324.         tXVPV.ioVolIndex = index;
  325.  
  326.         anErr = PBXGetVolInfoSync(&tXVPV);    // get its ioVRefNum
  327.         if (anErr == nsvErr)            // if no such volume...
  328.             anErr = afpItemNotFound;    // ...return application information not found
  329.         if (anErr != noErr)                // on error...
  330.             break;                        // ...break
  331.  
  332.         anErr = Search_Volume(tXVPV.ioVRefNum,pTargetType,pTargetCreator,pFSSpecPtr);
  333.         if (anErr == noErr)                // if we found it...
  334.             break;                        // ...break
  335.     }
  336.     return anErr;
  337. }
  338.  
  339. static OSErr Search_Volume(const SInt16 pVRefNum,const OSType pTargetType,const OSType pTargetCreator,FSSpec* pFSSpecPtr)
  340. {
  341.     CSParamPtr tCSParamPtr;
  342.     OSErr anErr;
  343.  
  344.     if (!pFSSpecPtr)
  345.         return paramErr;
  346.  
  347.     tCSParamPtr = (CSParamPtr) NewPtrClear(sizeof(CSParam));
  348.     if (tCSParamPtr == nil)
  349.         return MemError();
  350.  
  351.     // initialize the parameter block
  352.     tCSParamPtr->ioVRefNum = pVRefNum;
  353.     tCSParamPtr->ioMatchPtr = pFSSpecPtr;
  354.     tCSParamPtr->ioSearchBits = fsSBFlFndrInfo;
  355.  
  356.     tCSParamPtr->ioReqMatchCount = 1;    // only looking for 1
  357.     tCSParamPtr->ioSearchTime = 0;        // no timeout
  358.  
  359.     tCSParamPtr->ioSearchInfo1 = (CInfoPBPtr) NewPtrClear(sizeof(CInfoPBRec));
  360.     tCSParamPtr->ioSearchInfo2 = (CInfoPBPtr) NewPtrClear(sizeof(CInfoPBRec));
  361.  
  362.     if (tCSParamPtr->ioSearchInfo1 && tCSParamPtr->ioSearchInfo2)
  363.     {
  364.         // Now see if we can create an 2K optimization buffer
  365.         tCSParamPtr->ioOptBuffer = NewPtr(2048);
  366.         if (tCSParamPtr->ioOptBuffer)
  367.             tCSParamPtr->ioOptBufSize = 2048;
  368.         else
  369.             tCSParamPtr->ioOptBufSize = 0;    // no buffer, sorry
  370.  
  371.         tCSParamPtr->ioSearchInfo1->hFileInfo.ioNamePtr = nil;
  372.         tCSParamPtr->ioSearchInfo2->hFileInfo.ioNamePtr = nil;
  373.         tCSParamPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdType = pTargetType;
  374.         tCSParamPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdCreator = pTargetCreator;
  375.  
  376.         tCSParamPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdCreator = 0xFFFFFFFF;
  377.         tCSParamPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdType = 0xFFFFFFFF;
  378.         
  379.         anErr = PBCatSearchSync(tCSParamPtr);        // search sync
  380. //        if ((anErr != noErr) || (tCSParamPtr->ioActMatchCount == 0))
  381.     }
  382.     else
  383.         anErr = MemError();
  384.  
  385.     // no matter what happened, kill all the memory we allocated
  386.     if (tCSParamPtr->ioSearchInfo1)
  387.         DisposePtr((Ptr)tCSParamPtr->ioSearchInfo1);
  388.  
  389.     if (tCSParamPtr->ioSearchInfo2)
  390.         DisposePtr((Ptr)tCSParamPtr->ioSearchInfo2);
  391.  
  392.     if (tCSParamPtr->ioOptBuffer)
  393.         DisposePtr((Ptr)tCSParamPtr->ioOptBuffer);
  394.  
  395.     DisposePtr((Ptr)tCSParamPtr);
  396.  
  397.     return(anErr);
  398. }
  399.  
  400. static OSErr Find_DTDB_APPL(const OSType pTargetCreator,FSSpec* pFSSpecPtr)
  401. {
  402.     SInt16    index;
  403.     OSErr    anErr = noErr;
  404.  
  405.     for (index = 1;;index++)    // for each volume...
  406.     {
  407.         XVolumeParam    tXVPV;
  408.         DTPBRec    deskTopDBRec;
  409.  
  410.         tXVPV.ioCompletion = nil;
  411.         tXVPV.ioNamePtr = nil;
  412.         tXVPV.ioVolIndex = index;
  413.  
  414.         anErr = PBXGetVolInfoSync(&tXVPV);    // get its ioVRefNum
  415.         if (anErr == nsvErr)            // if no such volume...
  416.             anErr = afpItemNotFound;    // ...return application information not found
  417.         if (anErr != noErr)                // on error...
  418.             break;                        // ...break
  419.  
  420.         // now get the DTDB for this volume
  421.         deskTopDBRec.ioNamePtr = nil;
  422.         deskTopDBRec.ioVRefNum = tXVPV.ioVRefNum;
  423.         anErr = PBDTGetPath( &deskTopDBRec );
  424.         if (anErr != noErr)
  425.             break;
  426.  
  427.         // look in this DTDB for the app with this creator
  428.         deskTopDBRec.ioCompletion = nil;
  429.         deskTopDBRec.ioNamePtr = pFSSpecPtr->name;
  430.         deskTopDBRec.ioIndex = 0;
  431.         deskTopDBRec.ioFileCreator = pTargetCreator;
  432.  
  433.         anErr = PBDTGetAPPLSync( &deskTopDBRec );
  434.         if (anErr == noErr)    // found it
  435.         {    // stuff our FSSpec
  436.             pFSSpecPtr->vRefNum = deskTopDBRec.ioVRefNum;
  437.             pFSSpecPtr->parID = deskTopDBRec.ioAPPLParID;
  438.             break;
  439.         }
  440.     }
  441.     return anErr;
  442. }
  443.